﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using DAL;
using DAL.Repositories;
using System.Xml;
using System.Xml.Linq;

// Parseing json
using System.Net;
// For at bruge nedenstående er følgende reference tilføjet: System.Web.Extensions
using System.Web.Script.Serialization;

namespace BLL
{
    public class MovieCTR : Interfaces.IMovieCTR
    {
        MovieRepository _movieRep;

        public MovieCTR()
        {
            _movieRep = new MovieRepository();
        }

        /// <summary>
        /// Get all movies
        /// </summary>
        /// <returns>All movies</returns>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="Exception"></exception>
        public IList<Movie> GetMovies()
        {
            return _movieRep.GetMovies();
        }

        /// <summary>
        /// Get all movies for cinema
        /// </summary>
        /// <returns>All movies in cinema</returns>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="Exception"></exception>
        public IList<Movie> GetMovies(Cinema cinema)
        {
            return _movieRep.GetMovies(cinema);
        }

        /// <summary>
        /// Add movie with actors to db
        /// </summary>
        /// <param Name="movie">Movie object to add</param>
        public void AddMovie(Movie movie)
        {
            _movieRep.AddMovie(movie);
        }

        /// <summary>
        /// Search imdb for movies with title
        /// </summary>
        /// <param Name="title">Title of movie</param>
        /// <returns>List of movies which contains title string</returns>
        public IList<Movie> SearchIMDBMovies(string title)
        {
            // get xml for title
            XDocument xmlDoc = GetXDocFromIMDBTitle(title);

            // create movies from xml
            return CreateMoviesFromXML(xmlDoc);
        }

        #region IMDBAPI

        /// <summary>
        /// Create movies from xml document
        /// </summary>
        /// <param Name="xmlDoc">Xml document</param>
        /// <returns>List of movies</returns>
        private IList<Movie> CreateMoviesFromXML(XDocument xmlDoc)
        {
            Int32 _tmpLength;
            List<Movie> movies = (
                from e in xmlDoc.Root.Elements("item")
                select new Movie
                {
                    Title = e.Elements("title").Any() ? e.Element("title").Value : null,
                    Description = e.Elements("plot_simple").Any() ? e.Element("plot_simple").Value : null,
                    Length = e.Elements("runtime").Any() ? (Int32.TryParse(e.Element("runtime").Value.Replace("min", ""), out _tmpLength) ? _tmpLength : -1) : -1,
                    Genre = (e.Elements("genres").Any() && e.Element("genres").HasElements) ? string.Join("/", e.Element("genres").Elements("item").Select(a => a.Value).ToArray()) : null,
                    ImgUrl = e.Elements("poster").Any() ? e.Element("poster").Value : null,

                    // Inner select to get actors from XML
                    Actors = (e.Elements("actors").Any() && e.Element("actors").HasElements) ? (from actor in e.Element("actors").Elements("item")
                                                                                                select new Actor
                                                                                                {
                                                                                                    Name = actor.Value
                                                                                                }).ToList() : null

                }).ToList();

            return movies;
        }

        /// <summary>
        /// Get xml document from IMDBAPI. Searches API from string
        /// </summary>
        /// <param Name="title">Title to search movies for</param>
        /// <returns>Xml with movies containing title</returns>
        private XDocument GetXDocFromIMDBTitle(string title)
        {
            try
            {
                string urlEncodedString = System.Web.HttpUtility.UrlEncode(title);
                string _uri = String.Format(@"http://imdbapi.org/?title={0}&type=xml&plot=simple&episode=1&limit=10&yg=0&mt=none&lang=en-US&offset=&aka=simple&release=simple&business=0&tech=0", urlEncodedString);
                return XDocument.Load(_uri);
            } 
            catch (Exception) 
            {
                throw;
            }
        }

        #endregion

        /// <summary>
        /// Get movie from id
        /// </summary>
        /// <param name="id">Id of movie</param>
        /// <returns>Movie with Id</returns>
        /// <exception cref="Exception"></exception>
        public Movie GetMovie(int id)
        {
            return _movieRep.GetMovie(id);
        }
    }
}
